
<!DOCTYPE html>

<html>
  
<!-- Mirrored from docs.sympy.org/latest/modules/physics/mechanics/linearize.html by HTTrack Website Copier/3.x [XR&CO'2014], Sat, 15 Jan 2022 03:28:37 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=utf-8" /><!-- /Added by HTTrack -->
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />

    <title>Linearization in Physics/Mechanics &#8212; SymPy 1.9 documentation</title>
    <link rel="stylesheet" type="text/css" href="../../../_static/pygments.css" />
    <link rel="stylesheet" type="text/css" href="../../../_static/default.css" />
    <link rel="stylesheet" type="text/css" href="../../../_static/graphviz.css" />
    <link rel="stylesheet" type="text/css" href="../../../_static/plot_directive.css" />
    <link rel="stylesheet" type="text/css" href="../../../../../live.sympy.org/static/live-core.css" />
    <link rel="stylesheet" type="text/css" href="../../../../../live.sympy.org/static/live-autocomplete.css" />
    <link rel="stylesheet" type="text/css" href="../../../../../live.sympy.org/static/live-sphinx.css" />
    
    <script data-url_root="../../../" id="documentation_options" src="../../../_static/documentation_options.js"></script>
    <script src="../../../_static/jquery.js"></script>
    <script src="../../../_static/underscore.js"></script>
    <script src="../../../_static/doctools.js"></script>
    <script src="../../../../../live.sympy.org/static/utilities.js"></script>
    <script src="../../../../../live.sympy.org/static/external/classy.js"></script>
    <script src="../../../../../live.sympy.org/static/live-core.js"></script>
    <script src="../../../../../live.sympy.org/static/live-autocomplete.js"></script>
    <script src="../../../../../live.sympy.org/static/live-sphinx.js"></script>
    <script async="async" src="../../../../../cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest8331.js?config=TeX-AMS_HTML-full"></script>
    <script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]]}})</script>
    
    <link rel="shortcut icon" href="../../../_static/sympy-notailtext-favicon.ico"/>
    <link href="linearize.html" rel="canonical" />
    
    <link rel="index" title="Index" href="../../../genindex.html" />
    <link rel="search" title="Search" href="../../../search.html" />
    <link rel="next" title="Nonminimal Coordinates Pendulum" href="examples/lin_pend_nonmin_example.html" />
    <link rel="prev" title="Symbolic Systems in Physics/Mechanics" href="symsystem.html" /> 
  </head><body>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../../../genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="../../../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="examples/lin_pend_nonmin_example.html" title="Nonminimal Coordinates Pendulum"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="symsystem.html" title="Symbolic Systems in Physics/Mechanics"
             accesskey="P">previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="../../../index.html">SymPy 1.9 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../../index.html" >SymPy Modules Reference</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="../index.html" >Physics</a> &#187;</li>
          <li class="nav-item nav-item-3"><a href="index.html" accesskey="U">Classical Mechanics</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="#">Linearization in Physics/Mechanics</a></li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <section id="linearization-in-physics-mechanics">
<h1>Linearization in Physics/Mechanics<a class="headerlink" href="#linearization-in-physics-mechanics" title="Permalink to this headline">¶</a></h1>
<p><a class="reference internal" href="index.html#module-sympy.physics.mechanics" title="sympy.physics.mechanics"><code class="xref py py-mod docutils literal notranslate"><span class="pre">sympy.physics.mechanics</span></code></a> includes methods for linearizing the generated equations of
motion (EOM) about an operating point (also known as the trim condition).
Note that this operating point doesn’t have to be an equilibrium position, it
just needs to satisfy the equations of motion.</p>
<p>Linearization is accomplished by taking the first order Taylor expansion of
the EOM about the operating point. When there are no dependent coordinates
or speeds this is simply the jacobian of the right hand side about <span class="math notranslate nohighlight">\(q\)</span> and <span class="math notranslate nohighlight">\(u\)</span>.
However, in the presence of constraints more care needs to be taken. The
linearization methods provided here handle these constraints correctly.</p>
<section id="background">
<h2>Background<a class="headerlink" href="#background" title="Permalink to this headline">¶</a></h2>
<p>In <a class="reference internal" href="index.html#module-sympy.physics.mechanics" title="sympy.physics.mechanics"><code class="xref py py-mod docutils literal notranslate"><span class="pre">sympy.physics.mechanics</span></code></a> we assume all systems can be represented in the following
general form:</p>
<div class="math notranslate nohighlight">
\[\begin{split}f_{c}(q, t) &amp;= 0_{l \times 1}\\
f_{v}(q, u, t) &amp;= 0_{m \times 1}\\
f_{a}(q, \dot{q}, u, \dot{u}, t) &amp;= 0_{m \times 1}\\
f_{0}(q, \dot{q}, t) + f_{1}(q, u, t) &amp;= 0_{n \times 1}\\
f_{2}(q, u, \dot{u}, t) + f_{3}(q, \dot{q}, u, r, t) +
f_{4}(q, \lambda, t) &amp;= 0_{(o-m+k) \times 1}\end{split}\]</div>
<p>where</p>
<div class="math notranslate nohighlight">
\[\begin{split}q, \dot{q} &amp; \in \mathbb{R}^n\\
u, \dot{u} &amp; \in \mathbb{R}^o\\
r &amp; \in \mathbb{R}^s\\
\lambda &amp; \in \mathbb{R}^k\end{split}\]</div>
<p>In this form,</p>
<ul class="simple">
<li><p><span class="math notranslate nohighlight">\(f_{c}\)</span> represents the configuration constraint equations</p></li>
<li><p><span class="math notranslate nohighlight">\(f_{v}\)</span> represents the velocity constraint equations</p></li>
<li><p><span class="math notranslate nohighlight">\(f_{a}\)</span> represents the acceleration constraint equations</p></li>
<li><p><span class="math notranslate nohighlight">\(f_{0}\)</span> and <span class="math notranslate nohighlight">\(f_{1}\)</span> form the kinematic differential equations</p></li>
<li><p><span class="math notranslate nohighlight">\(f_{2}\)</span>, <span class="math notranslate nohighlight">\(f_{3}\)</span>, and <span class="math notranslate nohighlight">\(f_{4}\)</span> form the dynamic differential equations</p></li>
<li><p><span class="math notranslate nohighlight">\(q\)</span> and <span class="math notranslate nohighlight">\(\dot{q}\)</span> are the generalized coordinates and their derivatives</p></li>
<li><p><span class="math notranslate nohighlight">\(u\)</span> and <span class="math notranslate nohighlight">\(\dot{u}\)</span> are the generalized speeds and their derivatives</p></li>
<li><p><span class="math notranslate nohighlight">\(r\)</span> is the system inputs</p></li>
<li><p><span class="math notranslate nohighlight">\(\lambda\)</span> is the Lagrange multipliers</p></li>
</ul>
<p>This generalized form is held inside the <code class="docutils literal notranslate"><span class="pre">Linearizer</span></code> class, which
performs the actual linearization. Both <code class="docutils literal notranslate"><span class="pre">KanesMethod</span></code> and
<code class="docutils literal notranslate"><span class="pre">LagrangesMethod</span></code> objects have methods for forming the linearizer using
the <code class="docutils literal notranslate"><span class="pre">to_linearizer</span></code> class method.</p>
<div class="topic">
<p class="topic-title">A Note on Dependent Coordinates and Speeds</p>
<p>If the system being linearized contains constraint equations, this results in
not all generalized coordinates being independent (i.e. <span class="math notranslate nohighlight">\(q_1\)</span> may depend on
<span class="math notranslate nohighlight">\(q_2\)</span>). With <span class="math notranslate nohighlight">\(l\)</span> configuration constraints, and <span class="math notranslate nohighlight">\(m\)</span> velocity constraints,
there are <span class="math notranslate nohighlight">\(l\)</span> dependent coordinates and <span class="math notranslate nohighlight">\(m\)</span> dependent speeds.</p>
<p>In general, you may pick any of the coordinates and speeds to be dependent,
but in practice some choices may result in undesirable singularites. Methods
for deciding which coordinates/speeds to make dependent is behind the scope of
this guide. For more information, please see <a class="reference internal" href="reference.html#blajer1994" id="id1"><span>[Blajer1994]</span></a>.</p>
</div>
<p>Once the system is coerced into the generalized form, the linearized EOM can be
solved for. The methods provided in <a class="reference internal" href="index.html#module-sympy.physics.mechanics" title="sympy.physics.mechanics"><code class="xref py py-mod docutils literal notranslate"><span class="pre">sympy.physics.mechanics</span></code></a> allow for two different
forms of the linearized EOM:</p>
<dl>
<dt><span class="math notranslate nohighlight">\(M\)</span>, <span class="math notranslate nohighlight">\(A\)</span>, and <span class="math notranslate nohighlight">\(B\)</span></dt><dd><p>In this form, the forcing matrix is linearized into two separate matrices <span class="math notranslate nohighlight">\(A\)</span>
and <span class="math notranslate nohighlight">\(B\)</span>. This is the default form of the linearized EOM. The resulting
equations are:</p>
<div class="math notranslate nohighlight">
\[\begin{split}M \begin{bmatrix} \delta \dot{q} \\ \delta \dot{u} \\ \delta \lambda \end{bmatrix} =
A \begin{bmatrix} \delta q_i \\ \delta u_i \end{bmatrix} + B \begin{bmatrix} \delta r \end{bmatrix}\end{split}\]</div>
<p>where</p>
<div class="math notranslate nohighlight">
\[\begin{split}M &amp;\in \mathbb{R}^{(n+o+k) \times (n+o+k)}\\
A &amp;\in \mathbb{R}^{(n+o+k) \times (n-l+o-m)}\\
B &amp;\in \mathbb{R}^{(n+o+k) \times s}\end{split}\]</div>
<p>Note that <span class="math notranslate nohighlight">\(q_i\)</span> and <span class="math notranslate nohighlight">\(u_i\)</span> are just the independent coordinates and speeds,
while <span class="math notranslate nohighlight">\(q\)</span> and <span class="math notranslate nohighlight">\(u\)</span> contains both the independent and dependent coordinates
and speeds.</p>
</dd>
<dt><span class="math notranslate nohighlight">\(A\)</span> and <span class="math notranslate nohighlight">\(B\)</span></dt><dd><p>In this form, the linearized EOM are brought into explicit first order form,
in terms of just the independent coordinates and speeds. This form is often
used in stability analysis or control theory. The resulting equations
are:</p>
<div class="math notranslate nohighlight">
\[\begin{split}\begin{bmatrix} \delta \dot{q_i} \\ \delta \dot{u_i} \end{bmatrix} =
A \begin{bmatrix} \delta q_i \\ \delta u_i \end{bmatrix} + B \begin{bmatrix} \delta r \end{bmatrix}\end{split}\]</div>
<p>where</p>
<div class="math notranslate nohighlight">
\[\begin{split}A &amp;\in \mathbb{R}^{(n-l+o-m) \times (n-l+o-m)}\\
B &amp;\in \mathbb{R}^{(n-l+o-m) \times s}\end{split}\]</div>
<p>To use this form set <code class="docutils literal notranslate"><span class="pre">A_and_B=True</span></code> in the <code class="docutils literal notranslate"><span class="pre">linearize</span></code> class method.</p>
</dd>
</dl>
</section>
<section id="linearizing-kane-s-equations">
<h2>Linearizing Kane’s Equations<a class="headerlink" href="#linearizing-kane-s-equations" title="Permalink to this headline">¶</a></h2>
<p>After initializing the <code class="docutils literal notranslate"><span class="pre">KanesMethod</span></code> object and forming <span class="math notranslate nohighlight">\(F_r\)</span> and <span class="math notranslate nohighlight">\(F_r^*\)</span>
using the <code class="docutils literal notranslate"><span class="pre">kanes_equations</span></code> class method, linearization can be accomplished
in a couple ways. The different methods will be demonstrated with a simple
pendulum system:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">sympy</span> <span class="kn">import</span> <span class="n">symbols</span><span class="p">,</span> <span class="n">Matrix</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">sympy.physics.mechanics</span> <span class="kn">import</span> <span class="o">*</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">q1</span> <span class="o">=</span> <span class="n">dynamicsymbols</span><span class="p">(</span><span class="s1">&#39;q1&#39;</span><span class="p">)</span>                     <span class="c1"># Angle of pendulum</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">u1</span> <span class="o">=</span> <span class="n">dynamicsymbols</span><span class="p">(</span><span class="s1">&#39;u1&#39;</span><span class="p">)</span>                     <span class="c1"># Angular velocity</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">q1d</span> <span class="o">=</span> <span class="n">dynamicsymbols</span><span class="p">(</span><span class="s1">&#39;q1&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">L</span><span class="p">,</span> <span class="n">m</span><span class="p">,</span> <span class="n">t</span><span class="p">,</span> <span class="n">g</span> <span class="o">=</span> <span class="n">symbols</span><span class="p">(</span><span class="s1">&#39;L, m, t, g&#39;</span><span class="p">)</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># Compose world frame</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">N</span> <span class="o">=</span> <span class="n">ReferenceFrame</span><span class="p">(</span><span class="s1">&#39;N&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pN</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="s1">&#39;N*&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pN</span><span class="o">.</span><span class="n">set_vel</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># A.x is along the pendulum</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">A</span> <span class="o">=</span> <span class="n">N</span><span class="o">.</span><span class="n">orientnew</span><span class="p">(</span><span class="s1">&#39;A&#39;</span><span class="p">,</span> <span class="s1">&#39;axis&#39;</span><span class="p">,</span> <span class="p">[</span><span class="n">q1</span><span class="p">,</span> <span class="n">N</span><span class="o">.</span><span class="n">z</span><span class="p">])</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">A</span><span class="o">.</span><span class="n">set_ang_vel</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">u1</span><span class="o">*</span><span class="n">N</span><span class="o">.</span><span class="n">z</span><span class="p">)</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># Locate point P relative to the origin N*</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">P</span> <span class="o">=</span> <span class="n">pN</span><span class="o">.</span><span class="n">locatenew</span><span class="p">(</span><span class="s1">&#39;P&#39;</span><span class="p">,</span> <span class="n">L</span><span class="o">*</span><span class="n">A</span><span class="o">.</span><span class="n">x</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">vel_P</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">v2pt_theory</span><span class="p">(</span><span class="n">pN</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">A</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pP</span> <span class="o">=</span> <span class="n">Particle</span><span class="p">(</span><span class="s1">&#39;pP&#39;</span><span class="p">,</span> <span class="n">P</span><span class="p">,</span> <span class="n">m</span><span class="p">)</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># Create Kinematic Differential Equations</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">kde</span> <span class="o">=</span> <span class="n">Matrix</span><span class="p">([</span><span class="n">q1d</span> <span class="o">-</span> <span class="n">u1</span><span class="p">])</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># Input the force resultant at P</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">R</span> <span class="o">=</span> <span class="n">m</span><span class="o">*</span><span class="n">g</span><span class="o">*</span><span class="n">N</span><span class="o">.</span><span class="n">x</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># Solve for eom with kanes method</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">KM</span> <span class="o">=</span> <span class="n">KanesMethod</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">q_ind</span><span class="o">=</span><span class="p">[</span><span class="n">q1</span><span class="p">],</span> <span class="n">u_ind</span><span class="o">=</span><span class="p">[</span><span class="n">u1</span><span class="p">],</span> <span class="n">kd_eqs</span><span class="o">=</span><span class="n">kde</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fr</span><span class="p">,</span> <span class="n">frstar</span> <span class="o">=</span> <span class="n">KM</span><span class="o">.</span><span class="n">kanes_equations</span><span class="p">([</span><span class="n">pP</span><span class="p">],</span> <span class="p">[(</span><span class="n">P</span><span class="p">,</span> <span class="n">R</span><span class="p">)])</span>
</pre></div>
</div>
<section id="using-the-linearizer-class-directly">
<h3>1. Using the <code class="docutils literal notranslate"><span class="pre">Linearizer</span></code> class directly:<a class="headerlink" href="#using-the-linearizer-class-directly" title="Permalink to this headline">¶</a></h3>
<p>A linearizer object can be created using the <code class="docutils literal notranslate"><span class="pre">to_linearizer</span></code> class method.
This coerces the representation found in the <code class="docutils literal notranslate"><span class="pre">KanesMethod</span></code> object into the
generalized form described above. As the independent and dependent
coordinates and speeds are specified upon creation of the KanesMethod object,
there is no need to specify them here.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">linearizer</span> <span class="o">=</span> <span class="n">KM</span><span class="o">.</span><span class="n">to_linearizer</span><span class="p">()</span>
</pre></div>
</div>
<p>The linearized EOM can then be formed with the <code class="docutils literal notranslate"><span class="pre">linearize</span></code> method of the
<code class="docutils literal notranslate"><span class="pre">Linearizer</span></code> object:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">M</span><span class="p">,</span> <span class="n">A</span><span class="p">,</span> <span class="n">B</span> <span class="o">=</span> <span class="n">linearizer</span><span class="o">.</span><span class="n">linearize</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">M</span>
<span class="go">Matrix([</span>
<span class="go">[1,       0],</span>
<span class="go">[0, -L**2*m]])</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">A</span>
<span class="go">Matrix([</span>
<span class="go">[                 0, 1],</span>
<span class="go">[L*g*m*cos(q1(t)), 0]])</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">B</span>
<span class="go">Matrix(0, 0, [])</span>
</pre></div>
</div>
<p>Alternatively, the <span class="math notranslate nohighlight">\(A\)</span> and <span class="math notranslate nohighlight">\(B\)</span> form can be generated instead by specifying
<code class="docutils literal notranslate"><span class="pre">A_and_B=True</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">A</span><span class="p">,</span> <span class="n">B</span> <span class="o">=</span> <span class="n">linearizer</span><span class="o">.</span><span class="n">linearize</span><span class="p">(</span><span class="n">A_and_B</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">A</span>
<span class="go">Matrix([</span>
<span class="go">[                0, 1],</span>
<span class="go">[-g*cos(q1(t))/L, 0]])</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">B</span>
<span class="go">Matrix(0, 0, [])</span>
</pre></div>
</div>
<p>An operating point can also be specified as a dictionary or an iterable of
dictionaries. This will evaluate the linearized form at the specified
point before returning the matrices:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">op_point</span> <span class="o">=</span> <span class="p">{</span><span class="n">q1</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="n">u1</span><span class="p">:</span> <span class="mi">0</span><span class="p">}</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">A_op</span><span class="p">,</span> <span class="n">B_op</span> <span class="o">=</span> <span class="n">linearizer</span><span class="o">.</span><span class="n">linearize</span><span class="p">(</span><span class="n">A_and_B</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">op_point</span><span class="o">=</span><span class="n">op_point</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">A_op</span>
<span class="go">Matrix([</span>
<span class="go">[     0, 1],</span>
<span class="go">[-g/L, 0]])</span>
</pre></div>
</div>
<p>Note that the same effect can be had by applying <code class="docutils literal notranslate"><span class="pre">msubs</span></code> to the matrices
generated without the <code class="docutils literal notranslate"><span class="pre">op_point</span></code> kwarg:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">assert</span> <span class="n">msubs</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">op_point</span><span class="p">)</span> <span class="o">==</span> <span class="n">A_op</span>
</pre></div>
</div>
<p>Sometimes the returned matrices may not be in the most simplified form.
Simplification can be performed after the fact, or the <code class="docutils literal notranslate"><span class="pre">Linearizer</span></code> object
can be made to perform simplification internally by setting the <code class="docutils literal notranslate"><span class="pre">simplify</span></code>
kwarg to <code class="docutils literal notranslate"><span class="pre">True</span></code>.</p>
</section>
<section id="using-the-linearize-class-method">
<h3>2. Using the <code class="docutils literal notranslate"><span class="pre">linearize</span></code> class method:<a class="headerlink" href="#using-the-linearize-class-method" title="Permalink to this headline">¶</a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">linearize</span></code> method of the <code class="docutils literal notranslate"><span class="pre">KanesMethod</span></code> class is provided as a nice
wrapper that calls <code class="docutils literal notranslate"><span class="pre">to_linearizer</span></code> internally, performs the linearization,
and returns the result. Note that all the kwargs available in the
<code class="docutils literal notranslate"><span class="pre">linearize</span></code> method described above are also available here:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">A</span><span class="p">,</span> <span class="n">B</span><span class="p">,</span> <span class="n">inp_vec</span> <span class="o">=</span> <span class="n">KM</span><span class="o">.</span><span class="n">linearize</span><span class="p">(</span><span class="n">A_and_B</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">op_point</span><span class="o">=</span><span class="n">op_point</span><span class="p">,</span> <span class="n">new_method</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">A</span>
<span class="go">Matrix([</span>
<span class="go">[     0, 1],</span>
<span class="go">[-g/L, 0]])</span>
</pre></div>
</div>
<p>The additional output <code class="docutils literal notranslate"><span class="pre">inp_vec</span></code> is a vector containing all found
<code class="docutils literal notranslate"><span class="pre">dynamicsymbols</span></code> not included in the generalized coordinate or speed
vectors. These are assumed to be inputs to the system, forming the <span class="math notranslate nohighlight">\(r\)</span> vector
described in the background above. In this example there are no inputs, so
the vector is empty:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">inp_vec</span>
<span class="go">Matrix(0, 0, [])</span>
</pre></div>
</div>
<div class="topic">
<p class="topic-title">What’s with the <code class="docutils literal notranslate"><span class="pre">new_method</span></code> kwarg?</p>
<p>Previous releases of SymPy contained a linearization method for
<span class="math notranslate nohighlight">\(KanesMethod\)</span> objects. This method is deprecated, and will be removed
from future releases. Until then, you must set <code class="docutils literal notranslate"><span class="pre">new_method=True</span></code> in all
calls to <code class="docutils literal notranslate"><span class="pre">KanesMethod.linearize</span></code>. After the old method is removed, this
kwarg will no longer be needed.</p>
</div>
</section>
</section>
<section id="linearizing-lagrange-s-equations">
<h2>Linearizing Lagrange’s Equations<a class="headerlink" href="#linearizing-lagrange-s-equations" title="Permalink to this headline">¶</a></h2>
<p>Linearization of Lagrange’s equations proceeds much the same as that of
Kane’s equations. As before, the process will be demonstrated with a simple
pendulum system:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="c1"># Redefine A and P in terms of q1d, not u1</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">A</span> <span class="o">=</span> <span class="n">N</span><span class="o">.</span><span class="n">orientnew</span><span class="p">(</span><span class="s1">&#39;A&#39;</span><span class="p">,</span> <span class="s1">&#39;axis&#39;</span><span class="p">,</span> <span class="p">[</span><span class="n">q1</span><span class="p">,</span> <span class="n">N</span><span class="o">.</span><span class="n">z</span><span class="p">])</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">A</span><span class="o">.</span><span class="n">set_ang_vel</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">q1d</span><span class="o">*</span><span class="n">N</span><span class="o">.</span><span class="n">z</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">P</span> <span class="o">=</span> <span class="n">pN</span><span class="o">.</span><span class="n">locatenew</span><span class="p">(</span><span class="s1">&#39;P&#39;</span><span class="p">,</span> <span class="n">L</span><span class="o">*</span><span class="n">A</span><span class="o">.</span><span class="n">x</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">vel_P</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">v2pt_theory</span><span class="p">(</span><span class="n">pN</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">A</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pP</span> <span class="o">=</span> <span class="n">Particle</span><span class="p">(</span><span class="s1">&#39;pP&#39;</span><span class="p">,</span> <span class="n">P</span><span class="p">,</span> <span class="n">m</span><span class="p">)</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># Solve for eom with Lagrange&#39;s method</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Lag</span> <span class="o">=</span> <span class="n">Lagrangian</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">pP</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">LM</span> <span class="o">=</span> <span class="n">LagrangesMethod</span><span class="p">(</span><span class="n">Lag</span><span class="p">,</span> <span class="p">[</span><span class="n">q1</span><span class="p">],</span> <span class="n">forcelist</span><span class="o">=</span><span class="p">[(</span><span class="n">P</span><span class="p">,</span> <span class="n">R</span><span class="p">)],</span> <span class="n">frame</span><span class="o">=</span><span class="n">N</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">lag_eqs</span> <span class="o">=</span> <span class="n">LM</span><span class="o">.</span><span class="n">form_lagranges_equations</span><span class="p">()</span>
</pre></div>
</div>
<section id="id2">
<h3>1. Using the <code class="docutils literal notranslate"><span class="pre">Linearizer</span></code> class directly:<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h3>
<p>A <code class="docutils literal notranslate"><span class="pre">Linearizer</span></code> object can be formed from a <code class="docutils literal notranslate"><span class="pre">LagrangesMethod</span></code> object using
the <code class="docutils literal notranslate"><span class="pre">to_linearizer</span></code> class method. The only difference between this process
and that of the <code class="docutils literal notranslate"><span class="pre">KanesMethod</span></code> class is that the <code class="docutils literal notranslate"><span class="pre">LagrangesMethod</span></code> object
doesn’t already have its independent and dependent coordinates and speeds
specified internally. These must be specified in the call to
<code class="docutils literal notranslate"><span class="pre">to_linearizer</span></code>. In this example there are no dependent coordinates and
speeds, but if there were they would be included in the <code class="docutils literal notranslate"><span class="pre">q_dep</span></code> and
<code class="docutils literal notranslate"><span class="pre">qd_dep</span></code> kwargs:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">linearizer</span> <span class="o">=</span> <span class="n">LM</span><span class="o">.</span><span class="n">to_linearizer</span><span class="p">(</span><span class="n">q_ind</span><span class="o">=</span><span class="p">[</span><span class="n">q1</span><span class="p">],</span> <span class="n">qd_ind</span><span class="o">=</span><span class="p">[</span><span class="n">q1d</span><span class="p">])</span>
</pre></div>
</div>
<p>Once in this form, everything is the same as it was before with the
<code class="docutils literal notranslate"><span class="pre">KanesMethod</span></code> example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">A</span><span class="p">,</span> <span class="n">B</span> <span class="o">=</span> <span class="n">linearizer</span><span class="o">.</span><span class="n">linearize</span><span class="p">(</span><span class="n">A_and_B</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">op_point</span><span class="o">=</span><span class="n">op_point</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">A</span>
<span class="go">Matrix([</span>
<span class="go">[     0, 1],</span>
<span class="go">[-g/L, 0]])</span>
</pre></div>
</div>
</section>
<section id="id3">
<h3>2. Using the <code class="docutils literal notranslate"><span class="pre">linearize</span></code> class method:<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h3>
<p>Similar to <code class="docutils literal notranslate"><span class="pre">KanesMethod</span></code>, the <code class="docutils literal notranslate"><span class="pre">LagrangesMethod</span></code> class also provides a
<code class="docutils literal notranslate"><span class="pre">linearize</span></code> method as a nice wrapper that calls <code class="docutils literal notranslate"><span class="pre">to_linearizer</span></code>
internally, performs the linearization, and returns the result. As before, the
only difference is that the independent and dependent coordinates and speeds
must be specified in the call as well:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">A</span><span class="p">,</span> <span class="n">B</span><span class="p">,</span> <span class="n">inp_vec</span> <span class="o">=</span> <span class="n">LM</span><span class="o">.</span><span class="n">linearize</span><span class="p">(</span><span class="n">q_ind</span><span class="o">=</span><span class="p">[</span><span class="n">q1</span><span class="p">],</span> <span class="n">qd_ind</span><span class="o">=</span><span class="p">[</span><span class="n">q1d</span><span class="p">],</span> <span class="n">A_and_B</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">op_point</span><span class="o">=</span><span class="n">op_point</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">A</span>
<span class="go">Matrix([</span>
<span class="go">[     0, 1],</span>
<span class="go">[-g/L, 0]])</span>
</pre></div>
</div>
</section>
</section>
<section id="potential-issues">
<h2>Potential Issues<a class="headerlink" href="#potential-issues" title="Permalink to this headline">¶</a></h2>
<p>While the <code class="docutils literal notranslate"><span class="pre">Linearizer</span></code> class <em>should</em> be able to linearize all systems,
there are some potential issues that could occur. These are discussed below,
along with some troubleshooting tips for solving them.</p>
<section id="symbolic-linearization-with-a-and-b-true-is-slow">
<h3>1. Symbolic linearization with <code class="docutils literal notranslate"><span class="pre">A_and_B=True</span></code> is slow<a class="headerlink" href="#symbolic-linearization-with-a-and-b-true-is-slow" title="Permalink to this headline">¶</a></h3>
<p>This could be due to a number of things, but the most likely one is that
solving a large linear system symbolically is an expensive operation.
Specifying an operating point will reduce the expression size and speed
this up. If a purely symbolic solution is desired though (for application
of many operating points at a later period, for example) a way to get
around this is to evaluate with <code class="docutils literal notranslate"><span class="pre">A_and_B=False</span></code>, and then solve
manually after applying the operating point:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">M</span><span class="p">,</span> <span class="n">A</span><span class="p">,</span> <span class="n">B</span> <span class="o">=</span> <span class="n">linearizer</span><span class="o">.</span><span class="n">linearize</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">M_op</span> <span class="o">=</span> <span class="n">msubs</span><span class="p">(</span><span class="n">M</span><span class="p">,</span> <span class="n">op_point</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">A_op</span> <span class="o">=</span> <span class="n">msubs</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">op_point</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">perm_mat</span> <span class="o">=</span> <span class="n">linearizer</span><span class="o">.</span><span class="n">perm_mat</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">A_lin</span> <span class="o">=</span> <span class="n">perm_mat</span><span class="o">.</span><span class="n">T</span> <span class="o">*</span> <span class="n">M_op</span><span class="o">.</span><span class="n">LUsolve</span><span class="p">(</span><span class="n">A_op</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">A_lin</span>
<span class="go">Matrix([</span>
<span class="go">[     0, 1],</span>
<span class="go">[-g/L, 0]])</span>
</pre></div>
</div>
<p>The fewer symbols in <code class="docutils literal notranslate"><span class="pre">A</span></code> and <code class="docutils literal notranslate"><span class="pre">M</span></code> before solving, the faster this
solution will be. Thus, for large expressions, it may be to your benefit
to delay conversion to the <span class="math notranslate nohighlight">\(A\)</span> and <span class="math notranslate nohighlight">\(B\)</span> form until most symbols are subbed
in for their numeric values.</p>
</section>
<section id="the-linearized-form-has-nan-zoo-or-oo-as-matrix-elements">
<h3>2. The linearized form has <code class="docutils literal notranslate"><span class="pre">nan</span></code>, <code class="docutils literal notranslate"><span class="pre">zoo</span></code>, or <code class="docutils literal notranslate"><span class="pre">oo</span></code> as matrix elements<a class="headerlink" href="#the-linearized-form-has-nan-zoo-or-oo-as-matrix-elements" title="Permalink to this headline">¶</a></h3>
<p>There are two potential causes for this. The first (and the one you
should check first) is that some choices of dependent coordinates
will result in singularities at certain operating points. Coordinate
partitioning in a systemic manner to avoid this is beyond the scope
of this guide; see <a class="reference internal" href="reference.html#blajer1994" id="id4"><span>[Blajer1994]</span></a> for more information.</p>
<p>The other potential cause for this is that the matrices may not have
been in the most reduced form before the operating point was substituted
in. A simple example of this behavior is:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">sympy</span> <span class="kn">import</span> <span class="n">sin</span><span class="p">,</span> <span class="n">tan</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">expr</span> <span class="o">=</span> <span class="n">sin</span><span class="p">(</span><span class="n">q1</span><span class="p">)</span><span class="o">/</span><span class="n">tan</span><span class="p">(</span><span class="n">q1</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">op_point</span> <span class="o">=</span> <span class="p">{</span><span class="n">q1</span><span class="p">:</span> <span class="mi">0</span><span class="p">}</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">expr</span><span class="o">.</span><span class="n">subs</span><span class="p">(</span><span class="n">op_point</span><span class="p">)</span>
<span class="go">nan</span>
</pre></div>
</div>
<p>Note that if this expression was simplified before substitution, the
correct value results:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">expr</span><span class="o">.</span><span class="n">simplify</span><span class="p">()</span><span class="o">.</span><span class="n">subs</span><span class="p">(</span><span class="n">op_point</span><span class="p">)</span>
<span class="go">1</span>
</pre></div>
</div>
<p>A good way of avoiding this hasn’t been found yet. For expressions of
reasonable size, using <code class="docutils literal notranslate"><span class="pre">msubs</span></code> with <code class="docutils literal notranslate"><span class="pre">smart=True</span></code> will apply an
algorithm that tries to avoid these conditions. For large expressions
though this is extremely time consuming.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">msubs</span><span class="p">(</span><span class="n">expr</span><span class="p">,</span> <span class="n">op_point</span><span class="p">,</span> <span class="n">smart</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="go">1</span>
</pre></div>
</div>
</section>
</section>
<section id="further-examples">
<h2>Further Examples<a class="headerlink" href="#further-examples" title="Permalink to this headline">¶</a></h2>
<p>The pendulum example used above was simple, but didn’t include any dependent
coordinates or speeds. For a more thorough example, the same pendulum
was linearized with dependent coordinates using both Kane’s and Lagrange’s
methods:</p>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="examples/lin_pend_nonmin_example.html">Nonminimal Coordinates Pendulum</a><ul>
<li class="toctree-l2"><a class="reference internal" href="examples/lin_pend_nonmin_example.html#kane-s-method">Kane’s Method</a></li>
<li class="toctree-l2"><a class="reference internal" href="examples/lin_pend_nonmin_example.html#lagrange-s-method">Lagrange’s Method</a></li>
</ul>
</li>
</ul>
</div>
</section>
</section>


            <div class="clearer"></div>
          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
            <p class="logo"><a href="../../../index.html">
              <img class="logo" src="../../../_static/sympylogo.png" alt="Logo"/>
            </a></p>
  <h3><a href="../../../index.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Linearization in Physics/Mechanics</a><ul>
<li><a class="reference internal" href="#background">Background</a></li>
<li><a class="reference internal" href="#linearizing-kane-s-equations">Linearizing Kane’s Equations</a><ul>
<li><a class="reference internal" href="#using-the-linearizer-class-directly">1. Using the <code class="docutils literal notranslate"><span class="pre">Linearizer</span></code> class directly:</a></li>
<li><a class="reference internal" href="#using-the-linearize-class-method">2. Using the <code class="docutils literal notranslate"><span class="pre">linearize</span></code> class method:</a></li>
</ul>
</li>
<li><a class="reference internal" href="#linearizing-lagrange-s-equations">Linearizing Lagrange’s Equations</a><ul>
<li><a class="reference internal" href="#id2">1. Using the <code class="docutils literal notranslate"><span class="pre">Linearizer</span></code> class directly:</a></li>
<li><a class="reference internal" href="#id3">2. Using the <code class="docutils literal notranslate"><span class="pre">linearize</span></code> class method:</a></li>
</ul>
</li>
<li><a class="reference internal" href="#potential-issues">Potential Issues</a><ul>
<li><a class="reference internal" href="#symbolic-linearization-with-a-and-b-true-is-slow">1. Symbolic linearization with <code class="docutils literal notranslate"><span class="pre">A_and_B=True</span></code> is slow</a></li>
<li><a class="reference internal" href="#the-linearized-form-has-nan-zoo-or-oo-as-matrix-elements">2. The linearized form has <code class="docutils literal notranslate"><span class="pre">nan</span></code>, <code class="docutils literal notranslate"><span class="pre">zoo</span></code>, or <code class="docutils literal notranslate"><span class="pre">oo</span></code> as matrix elements</a></li>
</ul>
</li>
<li><a class="reference internal" href="#further-examples">Further Examples</a></li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="symsystem.html"
                        title="previous chapter">Symbolic Systems in Physics/Mechanics</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="examples/lin_pend_nonmin_example.html"
                        title="next chapter">Nonminimal Coordinates Pendulum</a></p>
  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="../../../_sources/modules/physics/mechanics/linearize.rst.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3 id="searchlabel">Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="https://docs.sympy.org/latest/search.html" method="get">
      <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
      <input type="submit" value="Go" />
    </form>
    </div>
</div>
<script>$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../../../genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="../../../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="examples/lin_pend_nonmin_example.html" title="Nonminimal Coordinates Pendulum"
             >next</a> |</li>
        <li class="right" >
          <a href="symsystem.html" title="Symbolic Systems in Physics/Mechanics"
             >previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="../../../index.html">SymPy 1.9 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../../index.html" >SymPy Modules Reference</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="../index.html" >Physics</a> &#187;</li>
          <li class="nav-item nav-item-3"><a href="index.html" >Classical Mechanics</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="#">Linearization in Physics/Mechanics</a></li> 
      </ul>
    </div>
    <div class="footer" role="contentinfo">
        &#169; Copyright 2021 SymPy Development Team.
      Last updated on Sep 30, 2021.
      Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 4.1.2.
    </div>
  </body>

<!-- Mirrored from docs.sympy.org/latest/modules/physics/mechanics/linearize.html by HTTrack Website Copier/3.x [XR&CO'2014], Sat, 15 Jan 2022 03:28:37 GMT -->
</html>